﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.ComponentModel.Design;

namespace PQT
{
    [ToolboxData("<{0}:PQTPager runat=server></{0}:PQTPager>")]
    [Designer(typeof(PQTPagingDesigner), typeof(IDesigner))]
    [DefaultProperty("CurrentPageIndex")]
    [DefaultBindingProperty("CurrentPageIndex")]
    public class PQTPager : WebControl, INamingContainer, IPostBackEventHandler, IPostBackDataHandler
    {
        private bool isDesignTime = false;
        private int startAt = 0;
        private int endAt = 0;

        /// <summary>
        /// PQTPager 
        /// </summary>
        public PQTPager()
            : base()
        {
            if (this.Context == null)
                this.isDesignTime = true;
        } // end of constructor

        /// <summary>
        /// 
        /// </summary>
        /// <param name="writer"></param>
        protected override void Render(HtmlTextWriter writer)
        {
            if (this.isDesignTime)
            {
                base.Render(writer);
                return;
            }

            CalculatePageData();

            int prevIndex = 0;
            int nextIndex = 0;

            string postBackScript;


            prevIndex = (this.startAt >= 0) ?
                this.CurrentPageIndex - 1 : 0;

            nextIndex = (this.endAt <= this.PageCount - 1) ?
                this.CurrentPageIndex + 1 : this.endAt;

            writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);
            writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);
            writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass);
            writer.RenderBeginTag(HtmlTextWriterTag.Span);

            // 처음 페이지로 이동 버튼
            postBackScript = this.Page.ClientScript.GetPostBackClientHyperlink(this, (0).ToString(), true);

            if (this.FirstPageImageUrl != string.Empty)
            {
                if (this.CurrentPageIndex > 0)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Src, this.Page.ResolveUrl(this.FirstPageImageUrl));
                    writer.AddAttribute(HtmlTextWriterAttribute.Onclick, postBackScript);
                    writer.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "Hand");
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass + "_img_first_page");
                }
                else
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Src, this.Page.ResolveUrl(this.FirstPageImageUrl));
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass + "_img_no_first_page");
                }
                writer.AddStyleAttribute(HtmlTextWriterStyle.VerticalAlign, "middle");
                writer.RenderBeginTag(HtmlTextWriterTag.Img);
                writer.RenderEndTag();
            }
            else
            {
                if (this.CurrentPageIndex > 0)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Href, postBackScript);
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass + "_first_page");
                    writer.RenderBeginTag(HtmlTextWriterTag.A);
                }
                else
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass + "_no_first_page");
                    writer.RenderBeginTag(HtmlTextWriterTag.Span);
                }

                writer.Write(this.FirstPageText);
                writer.RenderEndTag();
            }

            writer.Write("&nbsp;");

            // 이전 10 페이지 버튼
            postBackScript = this.Page.ClientScript.GetPostBackClientHyperlink(this, prevIndex.ToString(), true);

            if (this.PreviousButtonImageUrl != string.Empty)
            {
                if (this.CurrentPageIndex > 0)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Src, this.Page.ResolveUrl(this.PreviousButtonImageUrl));
                    writer.AddAttribute(HtmlTextWriterAttribute.Onclick, postBackScript);
                    writer.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "Hand");
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass + "_img_previous_page");

                }
                else
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Src, this.Page.ResolveUrl(this.PreviousButtonImageUrl));
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass + "_img_no_previous_page");

                }
                writer.AddStyleAttribute(HtmlTextWriterStyle.VerticalAlign, "middle");
                writer.RenderBeginTag(HtmlTextWriterTag.Img);
                writer.RenderEndTag();
            }
            else
            {
                if (this.CurrentPageIndex > 0)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Href, postBackScript);
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass + "_previous_page");
                    writer.RenderBeginTag(HtmlTextWriterTag.A);
                }
                else
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass + "_no_previous_page");
                    writer.RenderBeginTag(HtmlTextWriterTag.Span);
                }

                writer.Write(this.PreviousButtonText);
                writer.RenderEndTag();
            }

            writer.Write("&nbsp;");

            // 페이징 버튼
            for (int i = this.startAt; i <= this.endAt; i++)
            {
                postBackScript = this.Page.ClientScript.GetPostBackClientHyperlink(this, i.ToString(), true);
                if (i != this.CurrentPageIndex)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID + i.ToString());
                    writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID + i.ToString());
                    writer.AddAttribute(HtmlTextWriterAttribute.Href, postBackScript);
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass + "_no_hover");
                    writer.RenderBeginTag(HtmlTextWriterTag.A);
                }
                else
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, "active");
                    writer.RenderBeginTag(HtmlTextWriterTag.Span);
                }

                writer.Write(string.Format("{0}", i + 1));
                writer.RenderEndTag();
                writer.Write("&nbsp;");
            }



            // 다음 10 페이지 버튼
            postBackScript = this.Page.ClientScript.GetPostBackClientHyperlink(this, nextIndex.ToString(), true);

            if (this.NextButtonImageUrl != string.Empty)
            {
                if (this.CurrentPageIndex < this.PageCount - 1)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Src, this.Page.ResolveUrl(this.NextButtonImageUrl));
                    writer.AddAttribute(HtmlTextWriterAttribute.Onclick, postBackScript);
                    writer.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "Hand");
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass + "_img_previous_page");
                }
                else
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Src, this.Page.ResolveUrl(this.NextButtonImageUrl));
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass + "_img_no_previous_page");
                }
                writer.AddStyleAttribute(HtmlTextWriterStyle.VerticalAlign, "middle");
                writer.RenderBeginTag(HtmlTextWriterTag.Img);
                writer.RenderEndTag();
            }
            else
            {
                if (this.CurrentPageIndex < this.PageCount - 1)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Href, postBackScript);
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass + "_previous_page");
                    writer.RenderBeginTag(HtmlTextWriterTag.A);
                }
                else
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass + "_no_previous_page");
                    writer.RenderBeginTag(HtmlTextWriterTag.Span);
                }

                writer.Write(this.NextButtonText);
                writer.RenderEndTag();
            }

            writer.Write("&nbsp;");

            // 마지막 페이지로 이동 버튼
            postBackScript = this.Page.ClientScript.GetPostBackClientHyperlink(this, (PageCount - 1).ToString(), true);

            if (this.LastPageImageUrl != string.Empty)
            {
                if (this.CurrentPageIndex < PageCount - 1)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Src, this.Page.ResolveUrl(this.LastPageImageUrl));
                    writer.AddAttribute(HtmlTextWriterAttribute.Onclick, postBackScript);
                    writer.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "Hand");
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass + "_img_previous_page");

                }
                else
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Src, this.Page.ResolveUrl(this.LastPageImageUrl));
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass + "_img_no_previous_page");
                }
                writer.AddStyleAttribute(HtmlTextWriterStyle.VerticalAlign, "middle");
                writer.RenderBeginTag(HtmlTextWriterTag.Img);
                writer.RenderEndTag();
            }
            else
            {
                if (this.CurrentPageIndex < PageCount - 1)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Href, postBackScript);
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass + "_previous_page");
                    writer.RenderBeginTag(HtmlTextWriterTag.A);
                }
                else
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass + "_no_previous_page");
                    writer.RenderBeginTag(HtmlTextWriterTag.Span);
                }

                writer.Write(this.LastPageText);
                writer.RenderEndTag();
            }

            writer.RenderEndTag();
        }

        /// <summary>
        /// 
        /// </summary>
        private void CalculatePageData()
        {
            int pageCount = this.PageCount;

            this.startAt = (this.CurrentPageIndex / this.PagerButtonCount) * this.PagerButtonCount;
            this.endAt = this.startAt + (this.PagerButtonCount - 1);

            if (this.CurrentPageIndex % this.PagerButtonCount == this.PagerButtonCount - 1)
            {
                this.endAt = this.CurrentPageIndex + this.PagerButtonCount / 2;
                this.startAt = (this.CurrentPageIndex + this.PagerButtonCount / 2) - this.PagerButtonCount;
            }
            //else if (this.CurrentPageIndex == this.startAt && this.CurrentPageIndex != 0)
            //{
            //    this.startAt = this.CurrentPageIndex / 2;
            //    this.endAt = this.startAt + this.PagerButtonCount - 1;
            //}


            if (this.endAt > pageCount - 1)
                this.endAt = pageCount - 1;
        } // end of method CalculatePageData

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        internal int GetPageCount()
        {
            int pageCount = 0;
            pageCount = RecordCount / PageSize;

            if ((RecordCount % PageSize) > 0)
                pageCount++;

            return pageCount;
        }

        #region Property

        [Category("Data")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [PersistenceMode(PersistenceMode.Attribute)]
        public int CurrentPageIndex
        {
            get
            {
                if (this.ViewState["_currentPageIndex"] != null)
                {
                    return (int)this.ViewState["_currentPageIndex"];
                }
                return 0;
            }
            set
            {
                if ((int)value < 0)
                {
                    throw new ArgumentOutOfRangeException("value");
                }

                this.ViewState["_currentPageIndex"] = value;

                if ((int)value > this.PageCount - 1)
                    this.ViewState["_currentPageIndex"] = 0;
                else
                    this.ViewState["_currentPageIndex"] = value;
            }
        } // end of property CurrentPageIndex

        [Category("Data")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [PersistenceMode(PersistenceMode.Attribute)]
        public int PageCount
        {
            get
            {
                if (this.ViewState["_pageCount"] != null)
                {
                    return (int)this.ViewState["_pageCount"];
                }
                return 1;
            }
            internal set
            {
                if ((int)value < 0)
                {
                    throw new ArgumentOutOfRangeException("value");
                }

                this.ViewState["_pageCount"] = value;
            }
        } // end of property PageCount

        [Browsable(true)]
        [Category("Appearance")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [PersistenceMode(PersistenceMode.Attribute)]
        public int PageSize
        {
            get
            {
                /*if (this.ViewState["_pageSize"] != null)
                {
                    return (int)this.ViewState["_pageSize"];
                }*/
                return 13;
            }
            set
            {
                if ((int)value <= 0)
                {
                    throw new ArgumentOutOfRangeException("value");
                }

                this.ViewState["_pageSize"] = value;
                this.PageCount = GetPageCount();
            }
        } // end of property PageSize

        /// <summary>
        /// 전체 글의 개수를 가져오거나 설정합니다.
        /// </summary>
        [Browsable(true)]
        [Category("Data")]
        [DefaultValue(0)]
        [PersistenceMode(PersistenceMode.Attribute)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [Description("")]
        public int RecordCount
        {
            get
            {
                if (this.ViewState["_recordCount"] != null)
                {
                    return (int)this.ViewState["_recordCount"];
                }
                return 0;
            }
            set
            {
                if ((int)value < 0)
                {
                    throw new ArgumentOutOfRangeException("value");
                }

                this.ViewState["_recordCount"] = value;
                this.PageCount = GetPageCount();
            }
        } // end of property RecordCount

        [Browsable(true)]
        [Category("Appearance")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [PersistenceMode(PersistenceMode.Attribute)]
        public int PagerButtonCount
        {
            get
            {
                if (this.ViewState["_numericButtonCount"] != null)
                {
                    return (int)this.ViewState["_numericButtonCount"];
                }
                return 10;
            }
            set
            {
                if ((int)value <= 0)
                {
                    throw new ArgumentOutOfRangeException("value");
                }

                this.ViewState["_numericButtonCount"] = value;
            }
        } // end of property PagerButtonCount

        [Browsable(true)]
        [Category("Appearance")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [PersistenceMode(PersistenceMode.Attribute)]
        public string PreviousButtonText
        {
            get
            {
                if (this.ViewState["_prevPageText"] != null)
                {
                    return this.ViewState["_prevPageText"].ToString();
                }

                return "[Prev]";
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                {
                    throw new ArgumentNullException("value");
                }
                this.ViewState["_prevPageText"] = value;
            }
        } // end of property PreviousButtonText

        [Browsable(true)]
        [Category("Appearance")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [PersistenceMode(PersistenceMode.Attribute)]
        public string NextButtonText
        {
            get
            {
                if (this.ViewState["_nextPageText"] != null)
                {
                    return this.ViewState["_nextPageText"].ToString();
                }

                return "[Next]";
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                {
                    throw new ArgumentNullException("value");
                }
                this.ViewState["_nextPageText"] = value;
            }
        } // end of property NextButtonText

        [Browsable(true)]
        [Category("Appearance")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [PersistenceMode(PersistenceMode.Attribute)]
        public string PreviousButtonImageUrl
        {
            get
            {
                if (this.ViewState["_prevPageImgUrl"] != null)
                {
                    return this.ViewState["_prevPageImgUrl"].ToString();
                }

                return String.Empty;
            }
            set
            {
                this.ViewState["_prevPageImgUrl"] = value;
            }
        } // end of property PreviousButtonImageUrl

        [Browsable(true)]
        [Category("Appearance")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [PersistenceMode(PersistenceMode.Attribute)]
        public string NextButtonImageUrl
        {
            get
            {
                if (this.ViewState["_nextPageImgUrl"] != null)
                {
                    return this.ViewState["_nextPageImgUrl"].ToString();
                }

                return String.Empty;
            }
            set
            {
                this.ViewState["_nextPageImgUrl"] = value;
            }
        } // end of property NextButtonImageUrl

        [BrowsableAttribute(true)]
        [CategoryAttribute("Appearance")]
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [PersistenceModeAttribute(PersistenceMode.Attribute)]
        [DescriptionAttribute("")]
        public string FirstPageText
        {
            get
            {
                if (ViewState["_firstPageText"] != null)
                    return this.ViewState["_firstPageText"].ToString();

                return "[First]";
            }
            set
            {
                this.ViewState["_firstPageText"] = value;
            }
        } // end of property FirstPageText

        [BrowsableAttribute(true)]
        [CategoryAttribute("Appearance")]
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [PersistenceModeAttribute(PersistenceMode.Attribute)]
        [DescriptionAttribute("")]
        public string LastPageText
        {
            get
            {
                if (ViewState["_lastPageText"] != null)
                    return this.ViewState["_lastPageText"].ToString();

                return "[Last]";
            }
            set
            {
                this.ViewState["_lastPageText"] = value;
            }
        } // end of property LastPageText

        [BrowsableAttribute(true)]
        [CategoryAttribute("Appearance")]
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [PersistenceModeAttribute(PersistenceMode.Attribute)]
        [DescriptionAttribute("")]
        public string FirstPageImageUrl
        {
            get
            {
                if (ViewState["_firstPageImageUrl"] != null)
                    return this.ViewState["_firstPageImageUrl"].ToString();

                return string.Empty;
            }
            set
            {
                this.ViewState["_firstPageImageUrl"] = value;
            }
        } // end of propery FirstPageImageUrl

        [BrowsableAttribute(true)]
        [CategoryAttribute("Appearance")]
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [PersistenceModeAttribute(PersistenceMode.Attribute)]
        [DescriptionAttribute("")]
        public string LastPageImageUrl
        {
            get
            {
                if (ViewState["_lastPageImageUrl"] != null)
                    return this.ViewState["_lastPageImageUrl"].ToString();

                return string.Empty;
            }
            set
            {
                this.ViewState["_lastPageImageUrl"] = value;
            }
        } // end of property LastPageImageUrl

        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("NormalLink")]
        [Localizable(true)]
        public string NormalCssClass
        {
            get
            {
                if (ViewState["_normalCssClass"] != null)
                    return this.ViewState["_normalCssClass"].ToString();

                return string.Empty;
            }

            set
            {
                this.ViewState["_normalCssClass"] = value;
            }
        }

        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("Activelink")]
        [Localizable(true)]
        public string ActiveCssClass
        {
            get
            {
                if (ViewState["_activeCssClass"] != null)
                    return this.ViewState["_activeCssClass"].ToString();

                return string.Empty;
            }

            set
            {
                this.ViewState["_activeCssClass"] = value;
            }
        }

        #endregion

        public event PageIndexChangedEventHandler PageIndexChanged
        {
            add { base.Events.AddHandler("PageIndexChanged", value); }
            remove { base.Events.RemoveHandler("PageIndexChanged", value); }
        }

        protected virtual void OnPageIndexChanged(PageIndexChangedEventArgs e)
        {
            PageIndexChangedEventHandler handler = (PageIndexChangedEventHandler)base.Events["PageIndexChanged"];
            if (handler != null)
                handler(this.CurrentPageIndex, e);
        } // end of method OnPageIndexChanged

        public void RaisePostBackEvent(string eventArgument)
        {
            int newPage = 0;

            Int32.TryParse(eventArgument, out newPage);

            this.CurrentPageIndex = newPage;
            this.OnPageIndexChanged(new PageIndexChangedEventArgs(newPage));

            //this.OnPageIndexChanged(new PageIndexChangedEventArgs(Convert.ToInt32(eventArgument)));

        } // end of method RaisePostBackEvent

        public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
        {
            int currentPage = this.CurrentPageIndex;
            int newPage = 0;
            Int32.TryParse(postCollection[postDataKey], out newPage);

            if (currentPage != newPage)
            {
                this.CurrentPageIndex = newPage;
                return true;
            }
            return false;
        }

        public void RaisePostDataChangedEvent()
        {
            this.OnPageIndexChanged(new PageIndexChangedEventArgs(this.CurrentPageIndex));
        }
    } // end of class PQTPager

    public delegate void PageIndexChangedEventHandler(object sender, PageIndexChangedEventArgs e);

    public class PageIndexChangedEventArgs : EventArgs
    {
        private int newPageIndex = 0;

        public PageIndexChangedEventArgs(int newPage)
        {
            this.newPageIndex = newPage;
        } // end of method PageIndexChangedEventArgs

        public int NewPageIndex
        {
            get
            {
                return this.newPageIndex;
            }
        } // end of property NewPageIndex
    } // end of class PageIndexChangedEventArgs
}